package com.ostms.adv.service;

import android.annotation.SuppressLint;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.app.TaskStackBuilder;
import android.content.Context;
import android.content.Intent;
import android.media.AudioManager;
import android.os.Environment;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.telephony.PhoneStateListener;
import android.telephony.SignalStrength;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
import android.util.Log;

import com.alibaba.fastjson.JSONArray;
import com.google.gson.Gson;
import com.ostms.adv.BuildConfig;
import com.ostms.adv.R;
import com.ostms.adv.activity.FaceDetectActivity;
import com.ostms.adv.model.AdvRequestModle;
import com.ostms.adv.model.AppUpdateModle;
import com.ostms.adv.model.HeartBeatModel;
import com.ostms.adv.utils.CommonUtils;
import com.ostms.adv.utils.HttpTools;
import com.ostms.adv.utils.LOG;
import com.ostms.adv.utils.NetUtils;
import com.ostms.adv.utils.Tools;

import java.io.File;
import java.io.IOException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;

import okhttp3.Call;
import okhttp3.FormBody;
import okhttp3.MediaType;
import okhttp3.MultipartBody;
import okhttp3.RequestBody;

/**
 * Created by sun on 2017/12/9.
 */

public class MainBackService extends Service {
    private static final String TAG = MainBackService.class.getSimpleName();
    private static boolean isForever = true;
    private static final int REQUESTSUCCESS = 0;
    private static final int REQUESTFAILURE = 1;
    private static final int DOWNLOADSUCCESS = 2;
    private static final int DOWNLOADFAILED = 3;
    private static final int LOGUPLOADSUCCESS = 4;
    private static final int HEARTBEATSUCCESS = 5;
    private static final int WIFIMACDATASUCCESS = 6;
    private static final int HEARTBEATFAILURE = 7;
    private static final int REQUESTDEFAULTADVSUCCESS = 8;
    private static final int REQUESTDEFAULTADVFAILURE = 9;
    private static final int REQUESTDEFAULTADVFAILUREISEMPTY = 10;
    /**
     * 开机时间/关机时间
     */
    private static String startTime = null;
    private static String shutdownTime = null;
    private Context mContext;
    private String versionName;
    private HttpTools httpTools;
    private AudioManager audioManager;
    public static long rate = 30 * 1000;
    private static boolean downloadingVersion = false;
    @SuppressLint("HandlerLeak")
    private Handler mHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            if (msg.what == DOWNLOADSUCCESS) {
                String downUrl = (String) msg.obj;
                String appName = downUrl.substring(downUrl.lastIndexOf("/") + 1);
                String path = Environment.getExternalStorageDirectory().getPath() + "/aosen/app/" + appName;
                Tools.silentInstall(path, getApplicationContext());
                isDownLoadApk = true;
                //启动APP
                Intent intent = mContext.getPackageManager().getLaunchIntentForPackage("com.zsrt.ostms.adv");
                mContext.startActivity(intent);
            } else if (msg.what == DOWNLOADFAILED) {
                isDownLoadApk = true;
                AppUpdateModle modle = (AppUpdateModle) msg.obj;
                sendupdateStatus(modle.getPlanId());
            } else if (msg.what == LOGUPLOADSUCCESS) {
                List<String> zipPaths = (List<String>) msg.obj;
                for (int i = 0; i < zipPaths.size(); i++) {
                    new File(zipPaths.get(i)).delete();
                }
                LOG.i(TAG, "日志上传成功,并已删除本地日志");
            } else if (msg.what == HEARTBEATSUCCESS) {
                HeartBeatModel heartBeatModel = (HeartBeatModel) msg.obj;
                //检查是否有广告需要缓存
                Gson gson = new Gson();
                String json = gson.toJson(heartBeatModel);
                Tools.setProperties(mContext, CommonUtils.ADV_LIST, JSONArray.toJSONString(heartBeatModel.getList()));
                //根据心跳设置参数
                setHeartData(heartBeatModel);
            } else if (msg.what == HEARTBEATFAILURE) {
                Tools.setProperties(mContext, CommonUtils.ADV_LIST, null);
            } else if (msg.what == REQUESTFAILURE) {
            } else if (msg.what == REQUESTDEFAULTADVSUCCESS) {//缓存默认广告
                AdvRequestModle advRequestModle = (AdvRequestModle) msg.obj;
                Gson gson1 = new Gson();
                String json1 = gson1.toJson(advRequestModle);
                Tools.setProperties(mContext, CommonUtils.ADV_DEFAULTADV, json1);
            } else if (msg.what == REQUESTDEFAULTADVFAILUREISEMPTY) {
                Tools.setProperties(mContext, CommonUtils.ADV_DEFAULTADV, "");
            } else if (msg.what == REQUESTDEFAULTADVFAILURE) {
            }

        }
    };

    private void requestDefaultAdv() {
        String path = CommonUtils.DEFAULT_ADV;
        String equipmentCode = Tools.initEquipmentCode();
        FormBody.Builder builder = new FormBody.Builder();//创建表单请求体
        builder.add("equipmentCode", equipmentCode);
        httpTools.sendPostdata(path, builder, new HttpTools.HttpLisenner() {
            @Override
            public void onFailure(Call call, IOException e) {
                LOG.i(TAG, "requestDefaultAdv 失败:" + e.toString());
                mHandler.sendEmptyMessage(REQUESTDEFAULTADVFAILURE);
            }

            @Override
            public void onResponse(Call call, String result) {
                LOG.i(TAG, "requestDefaultAdv 成功:" + result);
                try {
                    if (null != result && result.length() > 0) {
                        Gson gson = new Gson();
                        AdvRequestModle advRequestModle = gson.fromJson(result, AdvRequestModle.class);
                        if (null != advRequestModle.getAds() && advRequestModle.getAds().size() > 0) {
                            Message msg = Message.obtain();
                            msg.what = REQUESTDEFAULTADVSUCCESS;
                            msg.obj = advRequestModle;
                            mHandler.sendMessage(msg);
                        } else {
                            mHandler.sendEmptyMessage(REQUESTDEFAULTADVFAILUREISEMPTY);
                        }
                    } else {
                        mHandler.sendEmptyMessage(REQUESTDEFAULTADVFAILUREISEMPTY);
                    }
                } catch (Exception e) {
                    mHandler.sendEmptyMessage(REQUESTDEFAULTADVFAILURE);
                }
            }
        });
    }

    private String defaultAdvStatus;

    private void setHeartData(HeartBeatModel heartBeatModel) {
        //判断是否更新默认广告
        defaultAdvStatus = heartBeatModel.getDefaultAdvStatus();
        if ("1".equals(defaultAdvStatus)) {
            requestDefaultAdv();
        }
        //强制上传日志
        if (CommonUtils.UPLOAD_LOG_TRUE.equals(heartBeatModel.getUploadLog())) {
            uploadLog(true);
        }
        if (CommonUtils.EQUIPMENT_STATUS_INVALID.equals(heartBeatModel.getEquipmentStatus())) {
            LOG.i(TAG, "当前设备已失效，请联系服务器管理员");
            return;
        } else if (CommonUtils.EQUIPMENT_STATUS_NO_CHECK.equals(heartBeatModel.getEquipmentStatus())) {
            LOG.i(TAG, "当前设备未认证，请管理员进行认证");
            return;
        } else if (CommonUtils.EQUIPMENT_STATUS_NO_REGISTER.equals(heartBeatModel.getEquipmentStatus())) {
            LOG.i(TAG, "当前设备未注册，即将自动注册当前设备");
            registerEqument();
            return;
        }
        AppUpdateModle appUpdateModle = heartBeatModel.getUpdatePlans();
        if (!"yibeimoudle".equals(BuildConfig.TARGET_CUSTOMER)) {//aar包不需要更新apk
            if ("1".equals(appUpdateModle.getUpdateStatus()) && Tools.checkVersion(Tools.getAppVersion(mContext), appUpdateModle.getVersion())) {
                Tools.setProperties(mContext, CommonUtils.PLAN_ID_SETTING, appUpdateModle.getPlanId());
                String downUrl = appUpdateModle.getDownUrl();
                if (null != downUrl) {
                    //下载新版APK
                    if (isDownLoadApk) {
                        isDownLoadApk = false;
                        LOG.i(TAG, "开始下载");
                        downLoadApk(appUpdateModle);
                    }
                }
            }
        }
        //心跳下发升级固件
        String deviceFirmwareVerion = Tools.getSystemProp("ro.product.version", "0.0.0.0");
        String webFirmwareVerion = heartBeatModel.getFirmwareVersion();
        LOG.i(TAG, "deviceFirmwareVerion = "+deviceFirmwareVerion+"   webFirmwareVerion = "+webFirmwareVerion);
        if((!TextUtils.isEmpty(webFirmwareVerion))&&(!"yibeimoudle".equals(BuildConfig.TARGET_CUSTOMER))){//aar包不需要更新固件
            if((deviceFirmwareVerion.compareToIgnoreCase(webFirmwareVerion)<0)&&(!downloadingVersion)) {
                downloadingVersion  = true;
                LOG.i(TAG, "心跳下发更新系统任务，即将下载新系统!");
                Intent mIntent = new Intent();
                mIntent.setClassName("com.ostsm.systemupgrade", "com.ostsm.systemupgrade.DownloadService");
                startService(mIntent);
            }
        }

        //删除广告OJBK  heartBeatModel.getDeleteAdv()
        if ("1".equals(heartBeatModel.getClearEquipment())) {
            Tools.deleteFiles(Environment.getExternalStorageDirectory() + "/aosen/adv/image/");
            Tools.deleteFiles(Environment.getExternalStorageDirectory() + "/aosen/adv/video/");
            isDelete = "0";
        } else {
            isDelete = "1";
        }

    }


    private boolean isDownLoadApk = true;
    private String isDelete;

    /**
     * //下载失败处理
     *
     * @param planId 计划更新id
     */
    private void sendupdateStatus(String planId) {
        LOG.i(TAG, "计划id==>" + planId);
        if (planId == null) {
            return;
        }
        String path = CommonUtils.STATUSCHANGE;
        FormBody.Builder builder = Tools.getOkHttpFormBodyBuilder(mContext);
        builder.add(CommonUtils.PLAN_ID, planId);
        builder.add(CommonUtils.STATUSCODE, CommonUtils.STATUSCODEFAILUR);

        httpTools.sendPostdata(path, builder, new HttpTools.HttpLisenner() {
            @Override
            public void onFailure(Call call, IOException e) {
                LOG.i(TAG, "更新计划状态上传失败:" + e);
            }

            @Override
            public void onResponse(Call call, String result) {
                LOG.i(TAG, "更新计划状态上传成功");
            }
        });
    }

    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public void onCreate() {
        super.onCreate();

    }

    @Override
    public void onDestroy() {
        super.onDestroy();
    }


    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        mContext = this;
        httpTools = new HttpTools(mContext);
        versionName = Tools.getAppVersion(mContext);
        audioManager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
        LOG.i(TAG, "后台服务(" + versionName + ")启动");
        //开始心跳
//        startGetMac();
        getNetworkQuality();
        requestForeverHeart();
        //APP更新检测
        isForever = true;
        //删除旧版的APK
        Tools.deleteOldApp();
        //检测内存
        checkMemeryUsed();
        //启动前台服务
        frontService();
        return START_NOT_STICKY;
    }

    /**
     * 60S检测一次内存是否使用满
     */
    private void checkMemeryUsed() {
        mHandler.postDelayed(new Runnable() {
            @Override
            public void run() {
                checkMemeryUsed();
                startCheckMemery();
            }
        }, 5 * 60 * 1000);
    }

    private void startCheckMemery() {
        //检测内存
        boolean b = Tools.checkMemmery(mContext);
        LOG.i(TAG, "是否满了：" + b);
        if (b) {
            List<File> imageList = Tools.getListTime("image");
            List<File> videoList = Tools.getListTime("video");
            System.out.println("删除前imageList：" + imageList.size());
            System.out.println("删除前videoList：" + videoList.size());
            if (imageList.size() > 0) {
                for (int i = 0; i < imageList.size() / 2; i++) {
                    File file = new File(imageList.get(i).getPath());
                    file.delete();
                }
            }
            if (videoList.size() > 0) {
                for (int i = 0; i < videoList.size() / 2; i++) {
                    File file = new File(videoList.get(i).getPath());
                    file.delete();
                }
            }
        }
    }

    /**
     * 30S请求一次心跳
     */
    private void requestForeverHeart() {
        mHandler.postDelayed(new Runnable() {
            @Override
            public void run() {
                requestForeverHeart();
                startHeart();
            }
        }, rate);
    }

    private void startHeart() {
        if (!Tools.checkRegister(mContext)) {
            //注册设备
            LOG.i(TAG, "设备为注册，即将开始注册设备");
            registerEqument();
        }
        //检查并上传昨天日志文件
        uploadLog(false);
        //发送心跳请求
        sendHeartPost();
    }

    private void registerEqument() {
        //向服务器注册设备
        String path = CommonUtils.REGISTER;
        FormBody.Builder builder = Tools.getOkHttpFormBodyBuilder(mContext);
        httpTools.sendPostdata(path, builder, new HttpTools.HttpLisenner() {
            @Override
            public void onFailure(Call call, IOException e) {
                LOG.i(TAG, "设备注册失败:" + e);
            }

            @Override
            public void onResponse(Call call, String result) {
                String equipmentKey = result == null ? null : result.trim();
                if (equipmentKey != null && !equipmentKey.equals("null") && !equipmentKey.equals("")) {
                    //注册成功
                    //保存到本地存储
                    if (!equipmentKey.contains("sysErrorMsg")) {
                        Tools.setProperties(mContext, CommonUtils.EQUIPMENT_KEY, equipmentKey);
                        LOG.i("EquipmentInfo.Register", "注册设备:" + equipmentKey + "即将开始心跳");
                    } else {
                        LOG.i("EquipmentInfo.Register", "自动注册设备失败!");
                    }
                } else {
                    LOG.i("EquipmentInfo.Register", "自动注册设备失败!");
                }
            }
        });
    }

    private void sendHeartPost() {
        String path = CommonUtils.HEARTBEAT;
        //设置参数
        String signal = NetUtils.getNetworkState(mContext);
//        log.i(TAG, "网络信息：" + signal);
        FormBody.Builder builder = Tools.getOkHttpFormBodyBuilder(mContext);
        builder.add("versionName", versionName);
        //设备网络信号强度
        if ("4G".equals(signal)) {
            builder.add("netSignal", getSignalData() + "");
        } else {
            builder.add("netSignal", "0");
        }

        if ("0".equals(isDelete)) {
            builder.add("ClearEquipment", isDelete);
        }
        builder.add("signal", signal);
        //设备可用内存
        builder.add("storage", Tools.getMemmery(mContext));
        //上传固件版本
        String firmwareVersion = Tools.getSystemProp("ro.product.version", "0.0.0.0");
        String boardType = Tools.getSystemProp("ro.product.type", "3288U").toUpperCase(Locale.ENGLISH);
        String payType = "SDK";
        if ( Tools.getSystemProp("ro.product.name", "").startsWith("FacePay")) {
            payType = "qingwa";
        }
        String firmware = boardType + "-" + payType + "-" + "V" + firmwareVersion;//eg :3288E-SDK-V1.0.0.0
        builder.add("firmware", firmware);
        //发送请求
        httpTools.sendPostdata(path, builder, new HttpTools.HttpLisenner() {
            @Override
            public void onFailure(Call call, IOException e) {
                LOG.i(TAG, "sendHeartPost心跳：" + e);
                mHandler.sendEmptyMessage(HEARTBEATFAILURE);
            }

            @Override
            public void onResponse(Call call, String result) {
                LOG.i(TAG, "sendHeartPost心跳：" + result);
                if (null != result && !"null".equals(result) && !"".equals(result)) {
                    result = result.trim();
                    if (result.contains("sysErrorMsg")) {
                        mHandler.sendEmptyMessage(HEARTBEATFAILURE);
                    } else {
                        try {
                            Gson gson = new Gson();
                            HeartBeatModel heartBeatModel = gson.fromJson(result, HeartBeatModel.class);
                            Message msg = Message.obtain();
                            msg.what = HEARTBEATSUCCESS;
                            msg.obj = heartBeatModel;
                            mHandler.sendMessage(msg);
                        } catch (Exception e) {
                            mHandler.sendEmptyMessage(HEARTBEATFAILURE);
                        }
                    }
                } else {
                    mHandler.sendEmptyMessage(HEARTBEATFAILURE);
                }
            }
        });

    }

    private long gsmSignalStrength;

    public void setSignalData(long gsmSignalStrength) {
        this.gsmSignalStrength = gsmSignalStrength;
    }

    public long getSignalData() {
        return gsmSignalStrength;
    }

    public void getNetworkQuality() {
        //获取telephonyManager
        TelephonyManager mTelephonyManager = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
        //监听信号强度
        mTelephonyManager.listen(new PhoneStateListener() {
            @Override
            public void onSignalStrengthsChanged(SignalStrength signalStrength) {
                super.onSignalStrengthsChanged(signalStrength);
                try {
                    Method levelMethod = SignalStrength.class.getDeclaredMethod("getLevel");
                    int level = (int) levelMethod.invoke(signalStrength);
                    setSignalData(level);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }, PhoneStateListener.LISTEN_SIGNAL_STRENGTHS);
    }

    /**
     * 上传日志文件
     *
     * @param isAll true:所有日志文件，false:除了今天的日志文件
     */
    private void uploadLog(boolean isAll) {
        List<String> pathList = new ArrayList<>();
        if (isAll) {
            pathList = Tools.getAllLogList(mContext);
        } else {
            pathList = Tools.getLogList(mContext);
        }
        LOG.i(TAG + ".uploadLog", "找到日志文件：" + pathList);
        if (null == pathList || pathList.size() == 0) {
            LOG.i(TAG, "找不到日志文件");
            return;
        }
        //对文件进行压缩处理,得到新的压缩文件绝对路径，删除原日志文件
        final List<String> zipPaths = Tools.zip(pathList);
        if (null == zipPaths || zipPaths.isEmpty()) {
            LOG.i(TAG, "压缩出错，没有得到压缩文件list");
            return;
        }
        //上传文件
        /**
         * 0 = "/mnt/internal_sd/aosen/log/remote/20181030_adv.zip"
         1 = "/mnt/internal_sd/aosen/log/remote/20181030_advException.zip"
         */
        String path = CommonUtils.LOGUPLOAD;
        MediaType type = MediaType.parse("application/octet-stream");
        MultipartBody.Builder multipartBody = Tools.getOkHttpMultipartBody(mContext);
        for (int i = 0; i < zipPaths.size(); i++) {
            File file = new File(zipPaths.get(i));
            String name = zipPaths.get(i).substring(zipPaths.get(i).lastIndexOf("/") + 1);
            RequestBody fileBody = RequestBody.create(type, file);
            multipartBody.addFormDataPart("file", name, fileBody);
        }
        httpTools.upLoadFile(path, multipartBody, new HttpTools.HttpLisenner() {
            @Override
            public void onFailure(Call call, IOException e) {
                LOG.i(TAG, "日志上传失败:" + e);
            }

            @Override
            public void onResponse(Call call, String result) {
                LOG.i(TAG, "日志上传成功");
                Message msg = Message.obtain();
                msg.obj = zipPaths;
                msg.what = LOGUPLOADSUCCESS;
                mHandler.sendMessage(msg);
            }
        });
    }

    public void downLoadApk(final AppUpdateModle appUpdateModle) {
        FormBody.Builder builder = new FormBody.Builder();
        builder.add("path", appUpdateModle.getDownUrl());
        String path = CommonUtils.DOWNLOAD;
        httpTools.downloadAPK(path, appUpdateModle.getDownUrl(), "aosen/app", builder, new HttpTools.OnDownloadListener() {
            @Override
            public void onDownloadSuccess() {
                System.out.println("下载成功");
                Message msg = Message.obtain();
                msg.what = DOWNLOADSUCCESS;
                msg.obj = appUpdateModle.getDownUrl();
                mHandler.sendMessage(msg);
            }

            @Override
            public void onDownloading(int progress) {
            }

            @Override
            public void onDownloadFailed() {
                System.out.println("下载失败");
                Message msg = Message.obtain();
                msg.what = DOWNLOADFAILED;
                msg.obj = appUpdateModle;
                mHandler.sendMessage(msg);
            }
        });
    }

    /**
     * 前台服务
     */
    private void frontService() {
        try {
            //创建通知详细信息
            Notification.Builder mBuilder = new Notification.Builder(this)
                    .setSmallIcon(R.mipmap.ic_launcher)
                    .setContentTitle("服务正在运行")
                    .setContentText("");
            //创建点击跳转Intent
            Intent intent = new Intent(this, FaceDetectActivity.class);
            //创建任务栈Builder
            TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);
            stackBuilder.addParentStack(FaceDetectActivity.class);
            stackBuilder.addNextIntent(intent);
            PendingIntent pendingIntent = stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);
            //设置跳转Intent到通知中
            mBuilder.setContentIntent(pendingIntent);
            //获取通知服务
            NotificationManager nm = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
            //构建通知
            Notification notification = mBuilder.build();
            //显示通知
            nm.notify(0, notification);
            //启动为前台服务
            startForeground(0, notification);
        } catch (Throwable e) {
            LOG.e(TAG + ".frontService", e);
        }
    }


}
